package com.manage.project.service.impl;

import cn.hutool.core.date.DateUtil;
import com.manage.common.exception.HxException;
import com.manage.config.MinioConfig;
import com.manage.project.bean.vo.FileUrl;
import com.manage.project.service.MinioService;
import com.manage.utils.FileTool;
import com.manage.utils.MinioTool;
import io.minio.MinioClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

@Slf4j
@Service
public class MinioServiceImpl implements MinioService {

    @Resource
    private MinioTool minioTool;

    @Resource
    private MinioConfig minioConfig;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////桶操作

    /**
     * 创建桶
     *
     * @param bucketName
     * @return
     */
    @Override
    public Boolean createBucket(String bucketName) {
        try {
            minioTool.makeBucket(bucketName);
        } catch (Exception e) {
            e.printStackTrace();
            throw new HxException("创建桶，操作失败！");
        }
        return true;
    }

    /**
     * 删除桶
     *
     * @param bucketName
     * @return
     */
    @Override
    public Boolean deleteBucket(String bucketName) {
        try {
            minioTool.removeBucket(bucketName);
        } catch (Exception e) {
            e.printStackTrace();
            throw new HxException("删除桶，操作失败！");
        }
        return true;
    }

    /**
     * 桶是否存在
     *
     * @param bucketName
     * @return
     */
    @Override
    public Boolean bucketExists(String bucketName) {
        Boolean exists = false;
        try {
            exists = minioTool.bucketExists(bucketName);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return exists;
    }

    @Override
    public List<String> listBucketNames() {
        List<String> bucketNames = new ArrayList<>();
        try {
            bucketNames = minioTool.listBucketNames();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bucketNames;
    }

    @Override
    public List<String> listFile(String bucketName) {
        List<String> fileNames = new ArrayList<>();
        try {
            fileNames = minioTool.listObjectNames(bucketName);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return fileNames;
    }

    @Override
    public FileUrl uploadFile(byte[] bytes, String bucketName) {
        FileUrl fileUrl = new FileUrl();
        InputStream inputStream = null;
        try {
            //如果存储桶不存在则创建
            boolean bucketExists = bucketExists(bucketName);
            //判断捅是否存在，如果不存在那么就创建捅:
            if (!bucketExists) {
                createBucket(bucketName);
            }

            //得到文件流····
            inputStream = new ByteArrayInputStream(bytes);
            //保证文件不重名(并且没有特殊字符)
            StringBuilder sb = new StringBuilder();
            sb.append(DateUtil.format(new Date(), "yyyyMMdd"));
            sb.append("/");
            String uuid = UUID.randomUUID().toString();
            String newuuid = uuid.replaceAll("-", "");
            sb.append(newuuid);
            sb.append(".jpg");
            String fileName = sb.toString();
            // 获得文件名
            minioTool.putObject(bucketName, fileName, inputStream);

            // 获取文件访问路径
            String endpoint = minioConfig.getEndpoint();
            String objectNameInBucket = bucketName + "/" + fileName;
            fileUrl.setUrl(endpoint + objectNameInBucket);
            fileUrl.setObjectName(objectNameInBucket);

        } catch (Exception e) {
            e.printStackTrace();
            throw new HxException("上传文件失败！");
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return fileUrl;
    }


    /**
     * 删除文件
     *
     * @param bucketName
     * @param fileName
     * @return
     */

    @Override
    public Boolean deleteFile(String bucketName, String fileName) {
        try {
            minioTool.removeObject(bucketName, fileName);
        } catch (Exception e) {
            throw new HxException("删除文件失败！");
        }
        return true;
    }

    @Override
    public Boolean deleteFiles(String bucketName, List<String> fileNames) {
        try {
            minioTool.removeObjects(bucketName, fileNames);
        } catch (Exception e) {
            e.printStackTrace();
            throw new HxException("删除文件失败！");
        }
        return true;
    }


    @Override
    public FileUrl uploadFile(MultipartFile file, @NotNull(message = "桶名必填") String bucketName) {
        FileUrl filePath = new FileUrl();
        try {
            MinioClient minioClient = minioConfig.getMinioClient();
            boolean bucketExists = minioClient.bucketExists(bucketName);
            if (!bucketExists) {
                throw new HxException(bucketName + "，桶不存在！");
            }
            // 上传
            String originalFilename = file.getOriginalFilename();
            String fileName = FileTool.createUniqueFileName(originalFilename);
            InputStream inputStream = file.getInputStream();
            minioTool.putObject(bucketName, fileName, inputStream);
            // 获取文件访问路径
            String endpoint = minioConfig.getEndpoint();
            String objectNameInBucket = bucketName + "/" + fileName;
            filePath.setUrl(endpoint + objectNameInBucket);
            filePath.setObjectName(objectNameInBucket);
        } catch (Exception e) {
            throw new HxException("上传失败！");
        }
        return filePath;
    }


}
